package com.sutong.platform.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sutong.common.result.ErrorCode;
import com.sutong.platform.constant.CommonConstant;
import com.sutong.platform.exception.BusinessException;
import com.sutong.platform.exception.ThrowUtils;
import com.sutong.platform.mapper.InterfaceParamMapper;
import com.sutong.platform.model.dto.interfaceparam.InterfaceParamQueryRequest;
import com.sutong.platform.model.entity.InterfaceParam;
import com.sutong.platform.model.vo.InterfaceParamVo;
import com.sutong.platform.service.InterfaceParamService;
import com.sutong.platform.utils.SqlUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author sutong
 * @description 接口参数响应信息Service实现
 */
@Service
public class InterfaceParamServiceImpl extends ServiceImpl<InterfaceParamMapper, InterfaceParam>
        implements InterfaceParamService {

    @Override
    public Wrapper<InterfaceParam> getQueryWrapper(InterfaceParamQueryRequest interfaceParamQueryRequest) {
        if (interfaceParamQueryRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
        }
        Long id = interfaceParamQueryRequest.getId();
        Long interfaceInfoId = interfaceParamQueryRequest.getInterfaceInfoId();
        String type = interfaceParamQueryRequest.getType();
        String name = interfaceParamQueryRequest.getName();
        String fieldType = interfaceParamQueryRequest.getFieldType();
        String description = interfaceParamQueryRequest.getDescription();
        Integer required = interfaceParamQueryRequest.getRequired();
        String sortField = interfaceParamQueryRequest.getSortField();
        String sortOrder = interfaceParamQueryRequest.getSortOrder();
        QueryWrapper<InterfaceParam> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjUtil.isNotNull(id), "id", id);
        queryWrapper.eq("pid", 0L);
        queryWrapper.eq(ObjUtil.isNotNull(interfaceInfoId), "interfaceInfoId", interfaceInfoId);
        queryWrapper.eq(StringUtils.isNotBlank(type), "type", type);
        queryWrapper.like(StringUtils.isNotBlank(name), "name", name);
        queryWrapper.eq(StringUtils.isNotBlank(fieldType), "fieldType", fieldType);
        queryWrapper.like(StringUtils.isNotBlank(description), "description", description);
        queryWrapper.eq(ObjUtil.isNotNull(required), "required", required);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC), sortField);
        return queryWrapper;
    }

    /**
     * 获取分页数据 包含孩子
     *
     * @param interfaceParamQueryRequest
     * @return
     */
    @Override
    public Page<InterfaceParamVo> pageWithChildren(InterfaceParamQueryRequest interfaceParamQueryRequest) {
        long current = interfaceParamQueryRequest.getCurrent();
        long size = interfaceParamQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        Page<InterfaceParam> page = page(new Page<>(current, size), getQueryWrapper(interfaceParamQueryRequest));
        // 填充下级
        List<InterfaceParam> records = page.getRecords();
        List<InterfaceParamVo> interfaceParamVos = records.stream().map(interfaceParam -> {
            InterfaceParamVo interfaceParamVo = BeanUtil.copyProperties(interfaceParam, InterfaceParamVo.class);
            List<InterfaceParamVo> children = getChildren(interfaceParam);
            interfaceParamVo.setChildren(CollUtil.isEmpty(children) ? null : children);
            return interfaceParamVo;
        }).collect(Collectors.toList());
        // 转化为Page<InterfaceParamVo>
        Page<InterfaceParamVo> voPage = new Page<>(current, size);
        BeanUtil.copyProperties(page, voPage);
        voPage.setRecords(interfaceParamVos);
        return voPage;
    }

    /**
     * 获取所有数据，树型
     *
     * @param interfaceInfoId
     * @param type
     * @return
     */
    @Override
    public List<InterfaceParamVo> listWithTree(long interfaceInfoId, int type) {
        List<InterfaceParam> all = lambdaQuery().eq(InterfaceParam::getInterfaceInfoId, interfaceInfoId).eq(InterfaceParam::getType, type).list();
        return all.stream()
                .filter(interfaceParam -> interfaceParam.getPid().equals(0L))
                .map(interfaceParam -> {
                    InterfaceParamVo interfaceParamVo = BeanUtil.copyProperties(interfaceParam, InterfaceParamVo.class);
                    List<InterfaceParamVo> children = getChildren(interfaceParam, all);
                    interfaceParamVo.setChildren(CollUtil.isEmpty(children) ? null : children);
                    return interfaceParamVo;
                })
                .collect(Collectors.toList());
    }


    private List<InterfaceParamVo> getChildren(InterfaceParam cur) {
        List<InterfaceParam> children = lambdaQuery().eq(InterfaceParam::getPid, cur.getId()).list();
        return children.stream()
                .map(interfaceParam -> {
                    InterfaceParamVo interfaceParamVo = BeanUtil.copyProperties(interfaceParam, InterfaceParamVo.class);
                    List<InterfaceParamVo> children2 = getChildren(interfaceParam);
                    interfaceParamVo.setChildren(CollUtil.isEmpty(children2) ? null : children2);
                    return interfaceParamVo;
                }).collect(Collectors.toList());
    }

    private List<InterfaceParamVo> getChildren(InterfaceParam cur, List<InterfaceParam> all) {
        return all.stream()
                .filter(interfaceParam -> cur.getId().equals(interfaceParam.getPid()))
                .map(interfaceParam -> {
                    InterfaceParamVo interfaceParamVo = BeanUtil.copyProperties(interfaceParam, InterfaceParamVo.class);
                    List<InterfaceParamVo> children = getChildren(interfaceParam, all);
                    interfaceParamVo.setChildren(CollUtil.isEmpty(children) ? null : children);
                    return interfaceParamVo;
                })
                .collect(Collectors.toList());
    }
}




